﻿using System.Linq;
using Daemon.Common;
using Daemon.Common.Helpers;
using Daemon.Infrustructure.EF;
using Daemon.Repository.EF.Enums;
using Daemon.Repository.Contract;
using Daemon.Model;
using System;
using System.Linq.Expressions;
using System.Collections.Generic;

namespace Daemon.Repository.EF
{
    public class IMOrganizationInfoRepository : Repository<IMOrganizationInfo, int>, IIMOrganizationInfoRepository
    {
        protected override Expression<Func<IMOrganizationInfo, int>> PrimaryKeyExpression => r => r.OrganizeId;

        public IMOrganizationInfoRepository(ApiDBContent context) : base(context)
        {
        }

        protected override IEnumerable<IMOrganizationInfo> IncludeRelationships(IEnumerable<IMOrganizationInfo> entities, ApiDBContent db)
        {
            SetBedInfo(entities, db);

            SetEmployeeInfo(entities, db);

            SetDeviceInfo(entities, db);

            return entities;
        }

        private void SetDeviceInfo(IEnumerable<IMOrganizationInfo> entities, ApiDBContent db)
        {
            if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, IMOrganizationInfoRelationship.DeviceInfo))
            {
                return;
            }

            var ids = entities.Select(r => r.OrganizeId).ToList();
            var deviceDic = db.IMDeviceQty.Where(r => ids.Contains(r.OrganizeId)).ToDictionary(r => r.OrganizeId, r => r.DeviceQty);
            foreach (var item in entities)
            {
                if (deviceDic.TryGetValue(item.OrganizeId, out int deviceQty))
                {
                    item.DeviceQty = deviceQty;
                }
            }
        }

        private void SetEmployeeInfo(IEnumerable<IMOrganizationInfo> entities, ApiDBContent db)
        {
            if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, IMOrganizationInfoRelationship.EmployeeInfo))
            {
                return;
            }

            var ids = entities.Select(r => r.OrganizeId).ToList();
            var employeeDic = db.IMEmployees.Where(r => ids.Contains(r.OrganizeId)).AsEnumerable().GroupBy(r => r.OrganizeId).ToDictionary(r => r.Key, r => r.ToList());
            foreach (var item in entities)
            {
                if (employeeDic.TryGetValue(item.OrganizeId, out List<IMEmployee> listEmployees))
                {
                    item.EmployeeQty = listEmployees.SelectMany(r => r.Name.Split('/')).ToList().Count();
                }
            }
        }

        private void SetBedInfo(IEnumerable<IMOrganizationInfo> entities, ApiDBContent db)
        {
            if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, IMOrganizationInfoRelationship.BedInfo))
            {
                return;
            }

            var ids = entities.Select(r => r.OrganizeId).ToList();
            var bedDic = db.BedInfos.Where(r => ids.Contains(r.OrganizeId)).ToList().GroupBy(r => r.OrganizeId).ToDictionary(r => r.Key, r => r.Count());
            foreach (var item in entities)
            {
                if (bedDic.TryGetValue(item.OrganizeId, out int bedCount))
                {
                    item.BedQty = bedCount;
                }
            }
        }
    }
}
